{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.1---Pandas数据结构-Series：基本概念及创建\n",
    "## “一维数组”Series"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0.544708\n",
      "1    0.634912\n",
      "2    0.480914\n",
      "3    0.801161\n",
      "4    0.913004\n",
      "dtype: float64\n",
      "<class 'pandas.core.series.Series'>\n",
      "RangeIndex(start=0, stop=5, step=1) <class 'pandas.core.indexes.range.RangeIndex'>\n",
      "[0.54470823 0.63491222 0.48091356 0.80116073 0.91300362] <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "# Series数据结构\n",
    "# Series是带有标签的一维数组，可以保存任何数据类型（整数、字符串、浮点数、Python对象等），轴标签统称为索引\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "# 导入Numpy，Pandas模块\n",
    "\n",
    "s = pd.Series(np.random.rand(5))        # Series的索引未必一定是数字，也可以是字母等等\n",
    "print(s)\n",
    "print(type(s))\n",
    "# 查看数据，数据类型\n",
    "\n",
    "print(s.index,type(s.index))     # index类似于一个生成器，要想输出可以用list()\n",
    "print(s.values,type(s.values))\n",
    "# .index查看series索引，类型为rangeindex\n",
    "# .values查看series值，类型是ndarray\n",
    "\n",
    "# 核心：series相比于ndarray，是一个自带索引index的数组 → 一维数组 + 对应索引\n",
    "# 所以当只看series的值的时候，就是一个ndarray\n",
    "# series和ndarray较相似，索引切片功能差别不大\n",
    "# series和dict相比，series更像一个有顺序的字典（dict本身不存在顺序），其索引原理与字典相似（一个用key，一个用index）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4    4\n",
      "5    5\n",
      "a    1\n",
      "b    2\n",
      "c    3\n",
      "dtype: int64 \n",
      " <class 'pandas.core.series.Series'>\n"
     ]
    }
   ],
   "source": [
    "# Series创建方法一：由字典创建，字典的key就是index，values就是values\n",
    "\n",
    "dic = {'a':1, 'b':2, 'c':3, '4':4, '5': 5}\n",
    "s =pd.Series(dic)\n",
    "print(s,'\\n',type(s))\n",
    "# 注意key肯定是字符串，假如values类型不止一个会怎么样？---> dic = {'a':1, 'b':'hello', 'c':3, '4':4, '5':5}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.39636219 0.80357757 0.53991881 0.38515742 0.04750525] \t <class 'numpy.ndarray'>\n",
      "0    0.396362\n",
      "1    0.803578\n",
      "2    0.539919\n",
      "3    0.385157\n",
      "4    0.047505\n",
      "dtype: float64 \t <class 'pandas.core.series.Series'>\n",
      "a     0.396362\n",
      "b     0.803578\n",
      "c     0.539919\n",
      "d     0.385157\n",
      "e    0.0475053\n",
      "dtype: object \n",
      " <class 'pandas.core.series.Series'>\n"
     ]
    }
   ],
   "source": [
    "# Series创建方法二：由数组创建（一维数组）\n",
    "\n",
    "arr =np.random.rand(5)\n",
    "s = pd.Series(arr)\n",
    "print(arr,'\\t',type(arr))\n",
    "print(s,'\\t',type(s))\n",
    "# 默认index是从0开始，步长为1的数字\n",
    "\n",
    "s = pd.Series(arr,index = list('abcde'),dtype = np.object)\n",
    "print(s,'\\n',type(s))\n",
    "# index参数：设置index，长度保持一致\n",
    "# dtype参数：设置数值类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    10\n",
      "1    10\n",
      "2    10\n",
      "3    10\n",
      "dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# Series创建方法三：由标量创建\n",
    "\n",
    "s = pd.Series(10, index = range(4))\n",
    "print(s)\n",
    "# 如果data是标量值，则必须提供索引。该值会重复，来匹配索引的长度。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0   -0.188485\n",
      "1    1.076107\n",
      "2   -1.228941\n",
      "3   -0.161078\n",
      "4   -0.907111\n",
      "dtype: float64\n",
      "------------------------------------------\n",
      "0   -2.030903\n",
      "1   -0.640124\n",
      "2    0.953726\n",
      "3    1.077311\n",
      "4   -0.409585\n",
      "Name: test, dtype: float64\n",
      "None test <class 'str'>\n",
      "0   -2.030903\n",
      "1   -0.640124\n",
      "2    0.953726\n",
      "3    1.077311\n",
      "4   -0.409585\n",
      "Name: hehehe, dtype: float64\n",
      "hehehe test\n"
     ]
    }
   ],
   "source": [
    "# Series名称属性：name\n",
    "\n",
    "s1 = pd.Series(np.random.randn(5))\n",
    "print(s1)\n",
    "print(\"------------------------------------------\")\n",
    "s2 = pd.Series(np.random.randn(5), name = 'test')\n",
    "print(s2)\n",
    "print(s1.name, s2.name, type(s2.name))\n",
    "# name为Series的一个参数，创建一个数组的名称\n",
    "# .name方法：输出数组的名称，输出格式为str，如果没有定义输出名称，输出为None\n",
    "\n",
    "s3 = s2.rename(\"hehehe\")\n",
    "print(s3)\n",
    "print(s3.name,s2.name)\n",
    "# .rename()方法：重命名一个数组的名称，并且新指向一个数组，原数组不变"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.2---Pandas数据结构-Series：索引\n",
    "## 位置下标 / 标签索引 / 切片索引 / 布尔型索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0.690311\n",
      "1    0.475359\n",
      "2    0.485334\n",
      "3    0.365693\n",
      "4    0.901511\n",
      "dtype: float64\n",
      "0.6903105273643406 <class 'numpy.float64'> float64\n",
      "0.6903105273643406 <class 'float'>\n"
     ]
    },
    {
     "ename": "KeyError",
     "evalue": "-1",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-6-b9a9102c047c>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mtype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mtype\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfloat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m \u001b[0mprint\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0ms\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m         \u001b[1;31m# 事实证明会报错！！！\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m      8\u001b[0m \u001b[1;31m# 位置下标从0开始\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;31m# 输出结果为numpy.float格式\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\python\\lib\\site-packages\\pandas\\core\\series.py\u001b[0m in \u001b[0;36m__getitem__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m    621\u001b[0m         \u001b[0mkey\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mcom\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_apply_if_callable\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    622\u001b[0m         \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m--> 623\u001b[1;33m             \u001b[0mresult\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_value\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m    624\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    625\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mis_scalar\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32md:\\python\\lib\\site-packages\\pandas\\core\\indexes\\base.py\u001b[0m in \u001b[0;36mget_value\u001b[1;34m(self, series, key)\u001b[0m\n\u001b[0;32m   2558\u001b[0m         \u001b[1;32mtry\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   2559\u001b[0m             return self._engine.get_value(s, k,\n\u001b[1;32m-> 2560\u001b[1;33m                                           tz=getattr(series.dtype, 'tz', None))\n\u001b[0m\u001b[0;32m   2561\u001b[0m         \u001b[1;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m \u001b[1;32mas\u001b[0m \u001b[0me1\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m   2562\u001b[0m             \u001b[1;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0\u001b[0m \u001b[1;32mand\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minferred_type\u001b[0m \u001b[1;32min\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;34m'integer'\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'boolean'\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_value\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_value\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32mpandas\\_libs\\index.pyx\u001b[0m in \u001b[0;36mpandas._libs.index.IndexEngine.get_loc\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;32mpandas\\_libs\\hashtable_class_helper.pxi\u001b[0m in \u001b[0;36mpandas._libs.hashtable.Int64HashTable.get_item\u001b[1;34m()\u001b[0m\n",
      "\u001b[1;31mKeyError\u001b[0m: -1"
     ]
    }
   ],
   "source": [
    "# 位置下标，类似序列\n",
    "\n",
    "s = pd.Series(np.random.rand(5))\n",
    "print(s)\n",
    "print(s[0], type(s[0]), s[0].dtype)\n",
    "print(float(s[0]),type(float(s[0])))\n",
    "print(s[-1])         # 事实证明会报错！！！                 \n",
    "# 位置下标从0开始\n",
    "# 输出结果为numpy.float格式\n",
    "# 可以通过float()函数转换为Python float 格式\n",
    "# numpy.float与float占用字节不同\n",
    "# s[-1]结果如何？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    0.249218\n",
      "b    0.168707\n",
      "c    0.377836\n",
      "d    0.457591\n",
      "e    0.514422\n",
      "dtype: float64\n",
      "0.24921796798069018 \t <class 'numpy.float64'> \t float64\n",
      "a    0.249218\n",
      "b    0.168707\n",
      "e    0.514422\n",
      "dtype: float64 \t <class 'pandas.core.series.Series'> \t float64\n"
     ]
    }
   ],
   "source": [
    "# 标签索引\n",
    "\n",
    "s = pd.Series(np.random.rand(5),index = list('abcde'))\n",
    "print(s)\n",
    "print(s['a'], '\\t', type(s['a']), '\\t', s['a'].dtype)\n",
    "# 方法类似下标索引，用[]表示，里面协商相应的index，注意，index是字符串\n",
    "\n",
    "sci = s[list('abe')]\n",
    "print(sci, '\\t', type(sci), '\\t', sci.dtype)\n",
    "# 如果需要选择多个标签的值，用[[]]来表示（相当于[]中包含一个列表）\n",
    "# 多标签索引结果是新的数组  注意：标签的顺序可以改变！！！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1    0.837221\n",
      "2    0.539634\n",
      "3    0.875737\n",
      "dtype: float64 \t 0.4989435351902991\n",
      "a    0.705824\n",
      "b    0.455990\n",
      "c    0.750291\n",
      "dtype: float64 \t 0.7502914417297876\n",
      "a    0.705824\n",
      "b    0.455990\n",
      "c    0.750291\n",
      "dtype: float64 \t 0.08594684319837054\n",
      "-------------------------------------------------\n",
      "a    0.705824\n",
      "b    0.455990\n",
      "c    0.750291\n",
      "d    0.085947\n",
      "dtype: float64\n",
      "a    0.705824\n",
      "c    0.750291\n",
      "e    0.198375\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 切片索引\n",
    "\n",
    "s1 = pd.Series(np.random.rand(5))\n",
    "s2 = pd.Series(np.random.rand(5), index = list('abcde'))\n",
    "print(s1[1:4], '\\t', s1[4])       # 下标\n",
    "print(s2['a':'c'],'\\t',s2['c']) #  标签\n",
    "print(s2[0:3],'\\t',s2[3])\n",
    "print(\"-------------------------------------------------\")\n",
    "# 注意：用index做切片是末端包含\n",
    "\n",
    "print(s2[:-1])\n",
    "print(s2[::2])\n",
    "# 下标索引做切片，和list写法一样"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    17.8675\n",
      "1    54.9716\n",
      "2    52.1081\n",
      "4       None\n",
      "dtype: object\n",
      "0    False\n",
      "1     True\n",
      "2     True\n",
      "4    False\n",
      "dtype: bool <class 'pandas.core.series.Series'> bool\n",
      "0    False\n",
      "1    False\n",
      "2    False\n",
      "4     True\n",
      "dtype: bool <class 'pandas.core.series.Series'> bool\n",
      "0     True\n",
      "1     True\n",
      "2     True\n",
      "4    False\n",
      "dtype: bool <class 'pandas.core.series.Series'> bool\n",
      "-----------------------------------------\n",
      "1    54.9716\n",
      "2    52.1081\n",
      "dtype: object\n",
      "0    17.8675\n",
      "1    54.9716\n",
      "2    52.1081\n",
      "dtype: object\n"
     ]
    }
   ],
   "source": [
    "# 布尔型索引\n",
    "\n",
    "s = pd.Series(np.random.rand(3)*100)\n",
    "s[4] = None      # 添加一个空值，将空值写成np.NaN也是可以的\n",
    "print(s)\n",
    "bs1 = s > 50\n",
    "bs2 = s.isnull()\n",
    "bs3 = s.notnull()\n",
    "print(bs1,type(bs1),bs1.dtype)\n",
    "print(bs2,type(bs2),bs2.dtype)\n",
    "print(bs3,type(bs3),bs3.dtype)\n",
    "print(\"-----------------------------------------\")\n",
    "# 数组作出判断之后，返回的是有一个布尔值组成的新的数组\n",
    "# .isnull() / .notnull() 方法判断是否为空值（None代表空值，NaN代表有问题的数值，两个都会识别为空值）\n",
    "\n",
    "print(s[s > 50])\n",
    "print(s[bs3])\n",
    "# 布尔型索引方法：用[判断条件]来进行表示，其中判断条件可以是一条语句，或者也可以是一个布尔型数组！"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.3---Pandas数据结构-Series：基本技巧\n",
    "## 数据查看 / 重新索引 / 对齐 / 添加、修改、删除值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0.339713\n",
      "1    0.841277\n",
      "2    0.829044\n",
      "3    0.053316\n",
      "4    0.945122\n",
      "5    0.297388\n",
      "6    0.593136\n",
      "7    0.887259\n",
      "8    0.712797\n",
      "9    0.402734\n",
      "dtype: float64\n",
      "45    0.097023\n",
      "46    0.172263\n",
      "47    0.751410\n",
      "48    0.201015\n",
      "49    0.417799\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 数据查看\n",
    "\n",
    "s = pd.Series(np.random.rand(50))\n",
    "print(s.head(10))\n",
    "print(s.tail())\n",
    "# .head()查看头部数据\n",
    "# .tail()查看尾部数据\n",
    "# 默认查看5条"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    0.641504\n",
      "b    0.238772\n",
      "c    0.719023\n",
      "dtype: float64\n",
      "c    0.719023\n",
      "b    0.238772\n",
      "a    0.641504\n",
      "d         NaN\n",
      "dtype: float64\n",
      "c    0.719023\n",
      "b    0.238772\n",
      "a    0.641504\n",
      "d    0.000000\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 重新索引reindex\n",
    "# .reindex将会根据索引重新排序，如果当前索引不存在，则会引入缺失值\n",
    "\n",
    "s = pd.Series(np.random.rand(3),index = list('abc'))\n",
    "print(s)\n",
    "s1 = s.reindex(list('cbad'))\n",
    "print(s1)\n",
    "# .reindex()中也是写列表\n",
    "# 注意：这里的'd'索引不存在，所以值为NaN\n",
    "\n",
    "s2 = s.reindex(list('cbad'),fill_value = 0)\n",
    "print(s2)\n",
    "# fill_value参数：填充缺失值的值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Jack     0.734995\n",
      "Marry    0.933204\n",
      "Tom      0.127558\n",
      "dtype: float64\n",
      "Wang     0.112632\n",
      "Jack     0.011946\n",
      "Marry    0.812446\n",
      "dtype: float64\n",
      "Jack     0.746941\n",
      "Marry    1.745649\n",
      "Tom           NaN\n",
      "Wang          NaN\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# Series对齐\n",
    "\n",
    "s1 = pd.Series(np.random.rand(3),index = ['Jack','Marry','Tom'])\n",
    "s2 = pd.Series(np.random.rand(3),index = ['Wang','Jack','Marry'])\n",
    "print(s1)\n",
    "print(s2)\n",
    "print(s1+s2)\n",
    "# Series 和 ndarray 之间的主要区别是，Series 上的操作会根据标签自动对齐\n",
    "# index顺序不会影响数值计算，以标签来计算\n",
    "# 空值和任何值计算结果扔为空值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "n    0.366744\n",
      "g    0.937997\n",
      "j    0.064086\n",
      "u    0.115443\n",
      "r    0.811429\n",
      "dtype: float64\n",
      "g    0.937997\n",
      "j    0.064086\n",
      "u    0.115443\n",
      "r    0.811429\n",
      "dtype: float64\n",
      "n    0.366744\n",
      "u    0.115443\n",
      "r    0.811429\n",
      "dtype: float64\n",
      "n    0.366744\n",
      "g    0.937997\n",
      "j    0.064086\n",
      "u    0.115443\n",
      "r    0.811429\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 删除：.drop\n",
    "\n",
    "s = pd.Series(np.random.rand(5), index = list('ngjur'))\n",
    "print(s)\n",
    "s1 = s.drop('n')\n",
    "s2 = s.drop(list('gj'))\n",
    "print(s1)\n",
    "print(s2)\n",
    "print(s)\n",
    "# drop 删除元素之后返回副本（inplace = False）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0    0.036616\n",
      "1    0.748492\n",
      "2    0.801879\n",
      "3    0.157206\n",
      "4    0.921338\n",
      "dtype: float64\n",
      "n    0.022153\n",
      "g    0.732041\n",
      "j    0.887380\n",
      "u    0.700776\n",
      "r    0.639713\n",
      "dtype: float64\n",
      "0      0.036616\n",
      "1      0.748492\n",
      "2      0.801879\n",
      "3      0.157206\n",
      "4      0.921338\n",
      "5    100.000000\n",
      "dtype: float64\n",
      "n      0.022153\n",
      "g      0.732041\n",
      "j      0.887380\n",
      "u      0.700776\n",
      "r      0.639713\n",
      "a    100.000000\n",
      "dtype: float64\n",
      "-------------------------------------------------\n",
      "0      0.036616\n",
      "1      0.748492\n",
      "2      0.801879\n",
      "3      0.157206\n",
      "4      0.921338\n",
      "5    100.000000\n",
      "n      0.022153\n",
      "g      0.732041\n",
      "j      0.887380\n",
      "u      0.700776\n",
      "r      0.639713\n",
      "a    100.000000\n",
      "dtype: float64\n",
      "0      0.036616\n",
      "1      0.748492\n",
      "2      0.801879\n",
      "3      0.157206\n",
      "4      0.921338\n",
      "5    100.000000\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 添加\n",
    "\n",
    "s1 = pd.Series(np.random.rand(5))\n",
    "s2 = pd.Series(np.random.rand(5), index = list('ngjur'))\n",
    "print(s1)\n",
    "print(s2)\n",
    "s1[5] = 100\n",
    "s2['a'] = 100\n",
    "print(s1)\n",
    "print(s2)\n",
    "print(\"-------------------------------------------------\")\n",
    "# 直接通过下标索引/标签index添加值\n",
    "\n",
    "s3 = s1.append(s2)\n",
    "print(s3)\n",
    "print(s1)\n",
    "# 通过.append()方法，直接添加一个数组\n",
    "# .append() 方法生成一个新的数组，不改变之前的数组"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a    0.169388\n",
      "b    0.025191\n",
      "c    0.789319\n",
      "dtype: float64\n",
      "a    100.0\n",
      "b    200.0\n",
      "c    200.0\n",
      "dtype: float64\n"
     ]
    }
   ],
   "source": [
    "# 修改\n",
    "\n",
    "s = pd.Series(np.random.rand(3),index = list('abc'))\n",
    "print(s)\n",
    "s['a'] = 100\n",
    "s[list('bc')] = 200\n",
    "print(s)\n",
    "# 通过索引直接修改，类似序列"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.4---Pandas数据结构DataFrame：基本概念及创建\n",
    "## “二维数组”Dataframe：是一个表格型的数据结构，包含一组有序的列，其列的值类型可以是数值，字符串，布尔值等等\n",
    "## Dataframe中的数据以一个或者多个二维块存放，不是列表，字典或者一维数组结构"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   age gender  name\n",
      "0   18      m  Jack\n",
      "1   19      m   Tom\n",
      "2   20      w  Mary\n",
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex(start=0, stop=3, step=1) \n",
      "该数据类型为： <class 'pandas.core.indexes.range.RangeIndex'>\n",
      "Index(['age', 'gender', 'name'], dtype='object') \n",
      "该数据类型为： <class 'pandas.core.indexes.base.Index'>\n",
      "[[18 'm' 'Jack']\n",
      " [19 'm' 'Tom']\n",
      " [20 'w' 'Mary']] \n",
      "该数据类型为： <class 'numpy.ndarray'>\n"
     ]
    }
   ],
   "source": [
    "# Dataframe数据结构\n",
    "# Dataframe是一个表格型的数据结构，“带有标签的二维数组”\n",
    "# Dataframe带有index（行标签）和columns（列标签）\n",
    "\n",
    "data = {'name':['Jack','Tom','Mary'],\n",
    "        'age':[18,19,20],\n",
    "        'gender':['m','m','w']\n",
    "       }\n",
    "frame = pd.DataFrame(data)\n",
    "print(frame)\n",
    "print(type(frame))\n",
    "print(frame.index, '\\n该数据类型为：',type(frame.index))\n",
    "print(frame.columns, '\\n该数据类型为：',type(frame.columns))\n",
    "print(frame.values, '\\n该数据类型为：',type(frame.values))\n",
    "# 查看数据，数据类型为Dataframe\n",
    "# .index查看行标签\n",
    "# .columns查看列标签\n",
    "# .values查看值，数据类型为ndarray"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a': [1, 2, 3], 'b': [3, 4, 5], 'c': [5, 6, 7]}\n",
      "{'one': array([0.28037544, 0.14699078, 0.80693857]), 'two': array([0.546477  , 0.72889235, 0.34602245])}\n",
      "   a  b  c\n",
      "0  1  3  5\n",
      "1  2  4  6\n",
      "2  3  5  7\n",
      "        one       two\n",
      "0  0.280375  0.546477\n",
      "1  0.146991  0.728892\n",
      "2  0.806939  0.346022\n",
      "   b  c  a    d\n",
      "0  3  5  1  NaN\n",
      "1  4  6  2  NaN\n",
      "2  5  7  3  NaN\n",
      "   b  c\n",
      "0  3  5\n",
      "1  4  6\n",
      "2  5  7\n",
      "         one       two\n",
      "f1  0.280375  0.546477\n",
      "f2  0.146991  0.728892\n",
      "f3  0.806939  0.346022\n"
     ]
    }
   ],
   "source": [
    "# Dataframe 创建方法一：由数组/list组成的字典\n",
    "# 创建方法：pd.DataFrame()\n",
    "\n",
    "data1 = {\n",
    "    'a':[1,2,3],\n",
    "    'b':[3,4,5],\n",
    "    'c':[5,6,7]\n",
    "        }\n",
    "data2 = {\n",
    "    'one':np.random.rand(3),\n",
    "    'two':np.random.rand(3)\n",
    "}                           # 这里如果尝试 'two': np.random.rand(4)会怎么样？\n",
    "print(data1)\n",
    "print(data2)\n",
    "df1 = pd.DataFrame(data1)\n",
    "df2 = pd.DataFrame(data2)\n",
    "print(df1)\n",
    "print(df2)\n",
    "# 注意：由数组/list构成的字典，创建Dataframe，cloumns为key，index为默认数字标签\n",
    "# ！！！字典的长度必须保持一致！！！\n",
    "\n",
    "df1 = pd.DataFrame(data1, columns = list('bcad'))\n",
    "print(df1)\n",
    "df1 = pd.DataFrame(data1, columns = list('bc'))\n",
    "print(df1)\n",
    "# columns参数：可以重新指定列的顺序，格式为list，如果现在数据中没有该列（比如'd'），则会产生NaN值\n",
    "# 如果columns重新指定时候，列的数量可以小于原数据\n",
    "\n",
    "df2 = pd.DataFrame(data2, index = ['f1','f2','f3'])  # 这里如果尝试  index = ['f1','f2','f3','f4'] 会怎么样？\n",
    "print(df2)\n",
    "# index参数：重新定义index，格式为list，长度必须保持一致"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'one': 0    0.491075\n",
      "1    0.422089\n",
      "dtype: float64, 'two': 0    0.756614\n",
      "1    0.831410\n",
      "2    0.871945\n",
      "dtype: float64}\n",
      "{'one': a    0.397379\n",
      "b    0.397216\n",
      "dtype: float64, 'two': a    0.501213\n",
      "b    0.518878\n",
      "c    0.211261\n",
      "dtype: float64}\n",
      "        one       two\n",
      "0  0.491075  0.756614\n",
      "1  0.422089  0.831410\n",
      "2       NaN  0.871945\n",
      "        one       two\n",
      "a  0.397379  0.501213\n",
      "b  0.397216  0.518878\n",
      "c       NaN  0.211261\n"
     ]
    }
   ],
   "source": [
    "# Dataframe 创建方法二：由Series组成的字典\n",
    "\n",
    "data1 = {\n",
    "    'one':pd.Series(np.random.rand(2)),\n",
    "    'two':pd.Series(np.random.rand(3))\n",
    "}                                    # 没有设置index的Series\n",
    "data2 = {\n",
    "    'one':pd.Series(np.random.rand(2),index = list('ab')),\n",
    "    'two':pd.Series(np.random.rand(3),index = list('abc'))\n",
    "}\n",
    "print(data1)\n",
    "print(data2)\n",
    "df1 = pd.DataFrame(data1)\n",
    "df2 = pd.DataFrame(data2)             # 若在这里更改index，并不会更改index，而是会指向新的标签！！！务必注意！！！\n",
    "print(df1)\n",
    "print(df2)\n",
    "# 由Seris组成的字典 创建Dataframe，columns为字典key，index为Series的标签（如果Series没有指定标签，则是默认数字标签）\n",
    "# Series可以长度不一样，生成的Dataframe会出现NaN值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.52176652 0.59638681 0.38100582]\n",
      " [0.38380165 0.38048098 0.75275102]\n",
      " [0.33906418 0.58788342 0.33444369]]\n",
      "          0         1         2\n",
      "0  0.521767  0.596387  0.381006\n",
      "1  0.383802  0.380481  0.752751\n",
      "2  0.339064  0.587883  0.334444\n",
      "        one       two     three\n",
      "a  0.521767  0.596387  0.381006\n",
      "b  0.383802  0.380481  0.752751\n",
      "c  0.339064  0.587883  0.334444\n"
     ]
    }
   ],
   "source": [
    "# Dataframe 创建方法三：通过二维数组直接创建\n",
    "\n",
    "ar = np.random.rand(9).reshape(3,3)\n",
    "print(ar)\n",
    "df1 = pd.DataFrame(ar)\n",
    "df2 = pd.DataFrame(ar, index = list('abc'), columns = ['one','two','three'])         # 可以尝试一下index或columns长度不等于已有数组的情况\n",
    "print(df1)\n",
    "print(df2)\n",
    "# 通过二维数组直接创建Dataframe，得到一样形状的结果数据，如果不指定index和columns，两者均返回默认数字格式\n",
    "# index和colunms指定长度与原数组保持一致"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[{'one': 1, 'two': 2}, {'one': 5, 'two': 10, 'three': 20}]\n",
      "   one  three  two\n",
      "0    1    NaN    2\n",
      "1    5   20.0   10\n",
      "   one  three  two\n",
      "a    1    NaN    2\n",
      "b    5   20.0   10\n",
      "   one  two\n",
      "0    1    2\n",
      "1    5   10\n"
     ]
    }
   ],
   "source": [
    "# Dataframe 创建方法四：由字典组成的列表\n",
    "\n",
    "data = [{'one': 1, 'two': 2}, {'one': 5, 'two': 10, 'three': 20}]\n",
    "print(data)\n",
    "df1 = pd.DataFrame(data)\n",
    "df2 = pd.DataFrame(data, index = ['a','b'])\n",
    "df3 = pd.DataFrame(data, columns = ['one','two'])\n",
    "print(df1)\n",
    "print(df2)\n",
    "print(df3)\n",
    "# 由字典组成的列表创建Dataframe，columns为字典的key，index不做指定则为默认数组标签\n",
    "# colunms和index参数分别重新指定相应列及行标签"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         Jack  Marry   Tom\n",
      "art        78     92   NaN\n",
      "english    89     95  67.0\n",
      "math       90     82  78.0\n",
      "         Jack   Tom  Bob\n",
      "art        78   NaN  NaN\n",
      "english    89  67.0  NaN\n",
      "math       90  78.0  NaN\n",
      "   Jack  Marry  Tom\n",
      "a   NaN    NaN  NaN\n",
      "b   NaN    NaN  NaN\n",
      "c   NaN    NaN  NaN\n"
     ]
    }
   ],
   "source": [
    "# Dataframe 创建方法五：由字典组成的字典\n",
    "\n",
    "data = {'Jack':{'math':90,'english':89,'art':78},\n",
    "       'Marry':{'math':82,'english':95,'art':92},\n",
    "       'Tom':{'math':78,'english':67}}\n",
    "df1 = pd.DataFrame(data)\n",
    "print(df1)\n",
    "# 由字典组成的字典创建Dataframe，columns为字典的key，index为子字典的key\n",
    "\n",
    "df2 = pd.DataFrame(data, columns = ['Jack','Tom','Bob'])\n",
    "df3 = pd.DataFrame(data, index = ['a','b','c'])\n",
    "print(df2)\n",
    "print(df3)\n",
    "# columns参数可以增加和减少现有列，如出现新的列，值为NaN\n",
    "# index在这里和之前不同，并不能改变原有index，如果指向新的标签，值为NaN （非常重要！）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.5---Pandas数据结构Dataframe：索引\n",
    "## Dataframe既有行索引也有列索引，可以被看做由Series组成的字典（共用一个索引）\n",
    "## 选择列 / 选择行 / 切片 / 布尔判断"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a          b          c          d\n",
      "one    83.779371  56.285376  86.873265  93.089983\n",
      "two    16.055004  23.748647  31.772143  15.622964\n",
      "three  24.665789  18.859390  38.126920   6.847767\n",
      "one      83.779371\n",
      "two      16.055004\n",
      "three    24.665789\n",
      "Name: a, dtype: float64 <class 'pandas.core.series.Series'>\n",
      "               a          c\n",
      "one    83.779371  86.873265\n",
      "two    16.055004  31.772143\n",
      "three  24.665789  38.126920 <class 'pandas.core.frame.DataFrame'>\n",
      "---------------------------------------------------\n",
      "a    83.779371\n",
      "b    56.285376\n",
      "c    86.873265\n",
      "d    93.089983\n",
      "Name: one, dtype: float64 <class 'pandas.core.series.Series'>\n",
      "             a          b          c          d\n",
      "one  83.779371  56.285376  86.873265  93.089983\n",
      "two  16.055004  23.748647  31.772143  15.622964 <class 'pandas.core.frame.DataFrame'>\n"
     ]
    }
   ],
   "source": [
    "# 选择行与列\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(12).reshape(3,4)*100,\n",
    "                 index = ['one','two','three'],\n",
    "                 columns = ['a','b','c','d']\n",
    "                 )\n",
    "print(df)\n",
    "data1 = df['a']\n",
    "data2 = df[['a','c']]\n",
    "print(data1,type(data1))\n",
    "print(data2,type(data2))\n",
    "print(\"---------------------------------------------------\")\n",
    "# 按照列名选择列，只选择一列输出Series，选择多列输出Dataframe\n",
    "\n",
    "data3 = df.loc['one']\n",
    "data4 = df.loc[['one','two']]\n",
    "print(data3,type(data3))\n",
    "print(data4,type(data4))\n",
    "# 按照index选择行，只选择一行输出Series，选择多行输出Dataframe"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              a         b         c         d\n",
      "one    0.474373  0.467418  0.953463  0.109177\n",
      "two    0.610307  0.226797  0.788088  0.752459\n",
      "three  0.654571  0.095461  0.944970  0.885476\n",
      "--------------------------------------------------\n",
      "one      0.474373\n",
      "two      0.610307\n",
      "three    0.654571\n",
      "Name: a, dtype: float64 \t <class 'pandas.core.series.Series'>\n",
      "              b         c\n",
      "one    0.467418  0.953463\n",
      "two    0.226797  0.788088\n",
      "three  0.095461  0.944970 \t <class 'pandas.core.frame.DataFrame'>\n",
      "            a         b         c         d\n",
      "one  0.474373  0.467418  0.953463  0.109177 <class 'pandas.core.frame.DataFrame'>\n"
     ]
    }
   ],
   "source": [
    "# df[]--- 选择列\n",
    "# 一般用于选择列，也可以选择行\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(3,4).reshape(3,4),\n",
    "                 index = ['one','two','three'],\n",
    "                 columns = list(\"abcd\")\n",
    "                 )\n",
    "print(df)\n",
    "print(\"--------------------------------------------------\")\n",
    "data1 = df['a']\n",
    "data2 = df[['b','c']]                          # # 尝试输入 data2 = df[['b','c','e']]\n",
    "print(data1,'\\t',type(data1))\n",
    "print(data2,'\\t',type(data2))\n",
    "# df[]默认选择列，[]中写列名（所以一般数据colunms都会单独制定，不会用默认数字列名，以免和index冲突）\n",
    "# 单选列为Series，print结果为Series格式\n",
    "# 多选列为Dataframe，print结果为Dataframe格式\n",
    "\n",
    "data3 = df[:1]\n",
    "# data3 = df[0]\n",
    "# data3 = df['one']\n",
    "print(data3,type(data3))\n",
    "# df[]中为数字时，默认选择行，且只能进行切片的选择，不能单独选择（df[0]）  此处务必要注意了！！！\n",
    "# 输出结果为Dataframe，即便只选择一行\n",
    "# df[]不能通过索引标签名来选择行(df['one'])\n",
    "\n",
    "# 核心笔记：df[col]一般用于选择列，[]中写列名"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a          b          c          d\n",
      "one    39.198392  24.962830  14.029617  33.007227\n",
      "two    96.797550  48.136346  31.453764  34.781173\n",
      "three  92.094622  79.169546  29.074811  18.559852\n",
      "four   89.539980  92.726186   7.467540  81.289885\n",
      "           a          b          c          d\n",
      "0  67.709251   1.485328  70.090358  86.362853\n",
      "1  60.418051  42.069528   1.930579  25.235333\n",
      "2  51.598369  10.377433  64.684472   3.397851\n",
      "3  27.294191  13.877274  10.602317  49.192797\n",
      "--------------------------------------------------\n",
      "a    39.198392\n",
      "b    24.962830\n",
      "c    14.029617\n",
      "d    33.007227\n",
      "Name: one, dtype: float64\n",
      "a    60.418051\n",
      "b    42.069528\n",
      "c     1.930579\n",
      "d    25.235333\n",
      "Name: 1, dtype: float64\n",
      "单标签索引\n",
      "------------------------------------------------------------------\n",
      "               a          b          c          d\n",
      "two    96.797550  48.136346  31.453764  34.781173\n",
      "three  92.094622  79.169546  29.074811  18.559852\n",
      "five         NaN        NaN        NaN        NaN\n",
      "           a          b          c          d\n",
      "3  27.294191  13.877274  10.602317  49.192797\n",
      "2  51.598369  10.377433  64.684472   3.397851\n",
      "1  60.418051  42.069528   1.930579  25.235333\n",
      "多标签索引\n",
      "-----------------------------------------------------------------\n",
      "               a          b          c          d\n",
      "one    39.198392  24.962830  14.029617  33.007227\n",
      "two    96.797550  48.136346  31.453764  34.781173\n",
      "three  92.094622  79.169546  29.074811  18.559852\n",
      "           a          b          c          d\n",
      "1  60.418051  42.069528   1.930579  25.235333\n",
      "2  51.598369  10.377433  64.684472   3.397851\n",
      "3  27.294191  13.877274  10.602317  49.192797\n",
      "--------切片索引--------\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "d:\\python\\lib\\site-packages\\ipykernel_launcher.py:21: FutureWarning: \n",
      "Passing list-likes to .loc or [] with any missing label will raise\n",
      "KeyError in the future, you can use .reindex() as an alternative.\n",
      "\n",
      "See the documentation here:\n",
      "http://pandas.pydata.org/pandas-docs/stable/indexing.html#deprecate-loc-reindex-listlike\n"
     ]
    }
   ],
   "source": [
    "# df.loc[]---按照index选择行\n",
    "\n",
    "df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                  index = ['one','two','three','four'],\n",
    "                  columns = list(\"abcd\")\n",
    "                  )\n",
    "df2 = pd.DataFrame(np.random.rand(4,4).reshape(4,4)*100,\n",
    "                  columns = list(\"abcd\")\n",
    "                  )\n",
    "print(df1)\n",
    "print(df2)\n",
    "print(\"--------------------------------------------------\")\n",
    "\n",
    "data1 = df1.loc['one']\n",
    "data2 = df2.loc[1]\n",
    "print(data1)\n",
    "print(data2)\n",
    "print('单标签索引\\n------------------------------------------------------------------')\n",
    "# 单个标签索引，返回Series\n",
    "\n",
    "data3 = df1.loc[['two','three','five']]\n",
    "data4 = df2.loc[[3,2,1]]\n",
    "print(data3)\n",
    "print(data4)\n",
    "print('多标签索引\\n-----------------------------------------------------------------')\n",
    "# 多个标签索引，如果标签不存在，则返回NaN\n",
    "# 顺序可变\n",
    "\n",
    "data5 = df1.loc['one':'three']\n",
    "data6 = df2.loc[1:3]\n",
    "print(data5)\n",
    "print(data6)\n",
    "str = '切片索引'\n",
    "print(\"{:-^20}\".format(str))\n",
    "# 可以做切片对象\n",
    "# 末端包含\n",
    "\n",
    "# 核心笔记：df.loc[label]主要针对index选择行，同时支持指定index，及默认数字index"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a          b          c          d\n",
      "one    67.008044  31.665447  42.100905  76.993404\n",
      "two     0.900278  28.284916  55.616162   4.003830\n",
      "three  28.757140  34.254015  16.757307  42.946138\n",
      "four   85.097424  64.501242  84.786248  87.951237\n",
      "----------------------------------------------------------\n",
      "a    67.008044\n",
      "b    31.665447\n",
      "c    42.100905\n",
      "d    76.993404\n",
      "Name: one, dtype: float64\n",
      "a    85.097424\n",
      "b    64.501242\n",
      "c    84.786248\n",
      "d    87.951237\n",
      "Name: four, dtype: float64\n",
      "单位置索引\n",
      "------------------------------------------------------------------\n",
      "               a          b          c          d\n",
      "one    67.008044  31.665447  42.100905  76.993404\n",
      "three  28.757140  34.254015  16.757307  42.946138\n",
      "               a          b          c          d\n",
      "four   85.097424  64.501242  84.786248  87.951237\n",
      "three  28.757140  34.254015  16.757307  42.946138\n",
      "two     0.900278  28.284916  55.616162   4.003830\n",
      "多位置索引\n",
      "-----------------------------------------------------------------\n",
      "               a          b          c          d\n",
      "two     0.900278  28.284916  55.616162   4.003830\n",
      "three  28.757140  34.254015  16.757307  42.946138\n",
      "               a          b          c          d\n",
      "one    67.008044  31.665447  42.100905  76.993404\n",
      "three  28.757140  34.254015  16.757307  42.946138\n",
      "切片索引\n"
     ]
    }
   ],
   "source": [
    "# df.iloc[]---按照整数位置（从轴的0到length-1）来选择行\n",
    "# 类似list的索引，其顺序就是Dataframe的整数位置，从0开始计数\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                 index = ['one','two','three','four'],\n",
    "                 columns = list('abcd')\n",
    "                 )\n",
    "print(df)\n",
    "print(\"----------------------------------------------------------\")\n",
    "\n",
    "print(df.iloc[0])\n",
    "print(df.iloc[-1])\n",
    "# print(df.iloc[4])\n",
    "print('单位置索引\\n------------------------------------------------------------------')\n",
    "# 单位置索引\n",
    "# 和loc索引不同，不能索引超出数据行数的整数位置\n",
    "\n",
    "print(df.iloc[[0,2]])\n",
    "print(df.iloc[[3,2,1]])\n",
    "print('多位置索引\\n-----------------------------------------------------------------')\n",
    "# 多位置索引\n",
    "# 顺序可变\n",
    "\n",
    "print(df.iloc[1:3])\n",
    "print(df.iloc[::2])\n",
    "print('切片索引')\n",
    "# 切片索引\n",
    "# 末端不包含   Note: 此处需要注意和.loc()方法的区别"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a          b          c          d\n",
      "one    25.163165  83.283309  49.134892  95.751979\n",
      "two    99.854598  65.429702  54.861576  97.490645\n",
      "three  54.456918   0.900533  71.109485   8.645579\n",
      "four   16.386811   4.927631  34.203624  71.825235\n",
      "-----------------------------------------------------------\n",
      "           a      b      c      d\n",
      "one    False  False  False  False\n",
      "two    False  False  False  False\n",
      "three  False   True  False   True\n",
      "four    True   True  False  False <class 'pandas.core.frame.DataFrame'>\n",
      "               a         b   c         d\n",
      "one          NaN       NaN NaN       NaN\n",
      "two          NaN       NaN NaN       NaN\n",
      "three        NaN  0.900533 NaN  8.645579\n",
      "four   16.386811  4.927631 NaN       NaN\n",
      "----------------------------------------------------------\n",
      "one      False\n",
      "two       True\n",
      "three     True\n",
      "four     False\n",
      "Name: a, dtype: bool <class 'pandas.core.series.Series'>\n",
      "               a          b          c          d\n",
      "two    99.854598  65.429702  54.861576  97.490645\n",
      "three  54.456918   0.900533  71.109485   8.645579\n",
      "---------------------------------------------------------\n",
      "           a      b\n",
      "one    False   True\n",
      "two     True   True\n",
      "three   True  False\n",
      "four   False  False <class 'pandas.core.frame.DataFrame'>\n",
      "               a          b   c   d\n",
      "one          NaN  83.283309 NaN NaN\n",
      "two    99.854598  65.429702 NaN NaN\n",
      "three  54.456918        NaN NaN NaN\n",
      "four         NaN        NaN NaN NaN\n",
      "---------------------------------------------------------\n",
      "           a      b      c      d\n",
      "one     True  False   True  False\n",
      "three  False   True  False   True <class 'pandas.core.frame.DataFrame'>\n",
      "               a         b          c         d\n",
      "one    25.163165       NaN  49.134892       NaN\n",
      "two          NaN       NaN        NaN       NaN\n",
      "three        NaN  0.900533        NaN  8.645579\n",
      "four         NaN       NaN        NaN       NaN\n",
      "---------------------------------------------------------\n"
     ]
    }
   ],
   "source": [
    "# 布尔型索引\n",
    "# 和Series原理相同\n",
    "\n",
    "df= pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                index = ['one','two','three','four'],\n",
    "                columns = list(\"abcd\")\n",
    "                )\n",
    "print(df)\n",
    "print(\"-----------------------------------------------------------\")\n",
    "\n",
    "b1 = df < 20\n",
    "print(b1,type(b1))\n",
    "print(df[b1])                      # 也可以书写为 df[df < 20]\n",
    "print(\"----------------------------------------------------------\")\n",
    "# 不做索引则会对数据的每个值进行判断\n",
    "# 索引结果保留所有数据：True返回原数据，False返回值为NaN\n",
    "\n",
    "b2 = df['a'] > 50\n",
    "print(b2,type(b2))\n",
    "print(df[b2])                    # 也可以书写为 df[df['a'] > 50]\n",
    "print(\"---------------------------------------------------------\")\n",
    "# 单列做判断\n",
    "# 索引结果保留，单列判断为True的行数据，包括其他列\n",
    "\n",
    "b3 = df[['a','b']] > 50\n",
    "print(b3,type(b3))\n",
    "print(df[b3])                # 也可以书写为 df[df[['a','b']] > 50]\n",
    "print(\"---------------------------------------------------------\")\n",
    "# 多列做判断\n",
    "# 索引结果保留 所有数据：True返回原数据，False返回值为NaN\n",
    "\n",
    "b4 = df.loc[['one','three']] < 50\n",
    "print(b4,type(b4))\n",
    "print(df[b4])              # 也可以书写为 df[df.loc[['one','three']] < 50]\n",
    "print(\"---------------------------------------------------------\")\n",
    "# 多行做判断\n",
    "# 索引结果保留 所有数据：True返回原数据，False返回值为NaN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               a          b          c          d\n",
      "one    23.048762  59.687004  10.267036  20.490032\n",
      "two    14.282800  72.669201  38.758915  40.448633\n",
      "three  39.150984  93.643248  47.786153  15.020371\n",
      "four   46.214493  62.561075  39.322810  20.039815\n",
      "--------------------------------------------------------------------\n",
      "one      23.048762\n",
      "three    39.150984\n",
      "Name: a, dtype: float64\n",
      "               b          c          d\n",
      "one    59.687004  10.267036  20.490032\n",
      "three  93.643248  47.786153  15.020371\n",
      "             a          b          c          d\n",
      "one  23.048762  59.687004  10.267036  20.490032\n",
      "two  14.282800  72.669201  38.758915  40.448633\n"
     ]
    }
   ],
   "source": [
    "# 多重索引：比如同时索引行和列\n",
    "# 注意：先选择列再选择行---相当于对于一个数据，先筛选字段，再选择数据量\n",
    "\n",
    "df= pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                index = ['one','two','three','four'],\n",
    "                columns = list('abcd')\n",
    "                )\n",
    "print(df)\n",
    "print(\"--------------------------------------------------------------------\")\n",
    "\n",
    "print(df['a'].loc[['one','three']])                            # 选择a列的one，three行\n",
    "print(df[['b','c','d']].iloc[::2])                            # 选择b，c，d列的one，three行\n",
    "print(df[df['a'] < 50].iloc[:2])                             # 选择满足判断索引的前两行数据  Note:如果选择列，可以：df[df['a]'<50][['a','b']]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2.6---Pandas数据结构Dataframe：基本技巧\n",
    "## 数据查看、转置 / 添加、修改、删除值 / 对齐 / 排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           a          b\n",
      "0  45.784533  67.697824\n",
      "1  11.838376  91.240721\n",
      "           a          b\n",
      "3  10.645220  58.668732\n",
      "4  12.078548  46.163054\n",
      "5  35.639371  26.747595\n",
      "6  62.481266  42.904762\n",
      "7  76.167404  76.338807\n",
      "           0          1          2          3          4          5  \\\n",
      "a  45.784533  11.838376  97.965373  10.645220  12.078548  35.639371   \n",
      "b  67.697824  91.240721  85.899184  58.668732  46.163054  26.747595   \n",
      "\n",
      "           6          7  \n",
      "a  62.481266  76.167404  \n",
      "b  42.904762  76.338807  \n"
     ]
    }
   ],
   "source": [
    "# 数据查看、转置\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(16).reshape(8,2)*100,\n",
    "                 columns = ['a','b']\n",
    "                 )\n",
    "print(df.head(2))\n",
    "print(df.tail())\n",
    "# .head()查看头部数据\n",
    "# .tail()查看尾部数据\n",
    "# 默认查看5条\n",
    "\n",
    "print(df.T)\n",
    "# .T 转置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           a          b          c          d\n",
      "0  32.631359  40.256404  40.576781  45.902410\n",
      "1  55.286121  33.676971  11.949312  79.405463\n",
      "2  89.640929  55.832964  58.947374  36.704955\n",
      "3  81.916838  92.923595  31.053016  15.945423\n",
      "           a          b          c          d   e\n",
      "0  32.631359  40.256404  40.576781  45.902410  10\n",
      "1  55.286121  33.676971  11.949312  79.405463  10\n",
      "2  89.640929  55.832964  58.947374  36.704955  10\n",
      "3  81.916838  92.923595  31.053016  15.945423  10\n",
      "4  20.000000  20.000000  20.000000  20.000000  20\n",
      "     a          b    c          d   e\n",
      "0  100  40.256404  100  45.902410  20\n",
      "1  100  33.676971  100  79.405463  20\n",
      "2  100  55.832964  100  36.704955  20\n",
      "3  100  92.923595  100  15.945423  20\n",
      "4  100  20.000000  100  20.000000  20\n"
     ]
    }
   ],
   "source": [
    "# 添加与修改\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                 columns = list('abcd')\n",
    "                 )\n",
    "print(df)\n",
    "\n",
    "df['e'] = 10\n",
    "df.loc[4] = 20\n",
    "print(df)\n",
    "# 新增列/行并且赋值\n",
    "\n",
    "df['e'] = 20\n",
    "df[['a','c']] = 100\n",
    "print(df)\n",
    "# 索引后直接修改值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           a          b          c          d\n",
      "0  24.808262  59.304360  57.549104  96.493986\n",
      "1  54.631284  38.374155  60.849887  45.405321\n",
      "2  43.132412   6.096231   1.180559  73.018923\n",
      "3  52.330936  77.563498  30.454008  92.882297\n",
      "           b          c          d\n",
      "0  59.304360  57.549104  96.493986\n",
      "1  38.374155  60.849887  45.405321\n",
      "2   6.096231   1.180559  73.018923\n",
      "3  77.563498  30.454008  92.882297\n",
      "-----------------------------------------------------\n",
      "           b          c          d\n",
      "1  38.374155  60.849887  45.405321\n",
      "2   6.096231   1.180559  73.018923\n",
      "3  77.563498  30.454008  92.882297\n",
      "           b          c          d\n",
      "0  59.304360  57.549104  96.493986\n",
      "3  77.563498  30.454008  92.882297\n",
      "           b          c          d\n",
      "0  59.304360  57.549104  96.493986\n",
      "1  38.374155  60.849887  45.405321\n",
      "2   6.096231   1.180559  73.018923\n",
      "3  77.563498  30.454008  92.882297\n",
      "-----------------------------------------------------\n",
      "           b          c\n",
      "0  59.304360  57.549104\n",
      "1  38.374155  60.849887\n",
      "2   6.096231   1.180559\n",
      "3  77.563498  30.454008\n",
      "           b          c          d\n",
      "0  59.304360  57.549104  96.493986\n",
      "1  38.374155  60.849887  45.405321\n",
      "2   6.096231   1.180559  73.018923\n",
      "3  77.563498  30.454008  92.882297\n"
     ]
    }
   ],
   "source": [
    "# 删除 del() / drop()\n",
    "\n",
    "df = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                 columns = list(\"abcd\")\n",
    "                 )\n",
    "print(df)\n",
    "\n",
    "del df['a']\n",
    "print(df)\n",
    "print(\"-----------------------------------------------------\")\n",
    "# del语句---删除列\n",
    "\n",
    "print(df.drop(0))\n",
    "print(df.drop([1,2]))\n",
    "print(df)\n",
    "print(\"-----------------------------------------------------\")\n",
    "# drop()删除行，inplace = False--->删除后生成新的数据，不改变原数据\n",
    "\n",
    "print(df.drop(['d'],axis = 1))\n",
    "print(df)\n",
    "# drop()删除列，需要加上axis = 1，inplace=False → 删除后生成新的数据，不改变原数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "          A         B         C   D\n",
      "0  0.265819  0.770987  1.300981 NaN\n",
      "1  0.675162  1.054662  2.324128 NaN\n",
      "2  3.182175  0.268563 -1.417100 NaN\n",
      "3 -0.125626  1.414944  0.429493 NaN\n",
      "4  1.074991  0.308236 -0.320261 NaN\n",
      "5 -1.000264 -0.747469  1.388564 NaN\n",
      "6 -0.334008 -0.219700 -0.216004 NaN\n",
      "7       NaN       NaN       NaN NaN\n",
      "8       NaN       NaN       NaN NaN\n",
      "9       NaN       NaN       NaN NaN\n"
     ]
    }
   ],
   "source": [
    "# 对齐\n",
    "\n",
    "df1 = pd.DataFrame(np.random.randn(10,4),columns = list('ABCD'))\n",
    "df2 = pd.DataFrame(np.random.randn(7,3),columns = list('ABC'))\n",
    "print(df1 + df2)\n",
    "# DataFrame对象之间的数据自动按照列和索引（行标签）对齐"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           a          b          c          d\n",
      "0  91.055481  45.090422  13.354916  20.727048\n",
      "1  86.867987  30.581833  52.916170  72.929333\n",
      "2  97.058462  48.299240  83.554918  61.990196\n",
      "3  80.279834  26.735496  74.633226  68.268991\n",
      "           a          b          c          d\n",
      "3  80.279834  26.735496  74.633226  68.268991\n",
      "1  86.867987  30.581833  52.916170  72.929333\n",
      "0  91.055481  45.090422  13.354916  20.727048\n",
      "2  97.058462  48.299240  83.554918  61.990196\n",
      "           a          b          c          d\n",
      "2  97.058462  48.299240  83.554918  61.990196\n",
      "0  91.055481  45.090422  13.354916  20.727048\n",
      "1  86.867987  30.581833  52.916170  72.929333\n",
      "3  80.279834  26.735496  74.633226  68.268991\n",
      "--------------------------------------------------------------------------\n",
      "   a  b  c\n",
      "0  1  0  8\n",
      "1  1  1  7\n",
      "2  1  2  6\n",
      "3  1  3  5\n",
      "4  2  4  4\n",
      "5  2  5  3\n",
      "6  2  6  2\n",
      "7  2  7  1\n",
      "   a  b  c\n",
      "3  1  3  5\n",
      "2  1  2  6\n",
      "1  1  1  7\n",
      "0  1  0  8\n",
      "7  2  7  1\n",
      "6  2  6  2\n",
      "5  2  5  3\n",
      "4  2  4  4\n"
     ]
    }
   ],
   "source": [
    "# 排序一：按值排序 .sort_values\n",
    "# 同样适用于Series\n",
    "\n",
    "df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                  columns = list('abcd')\n",
    "                  )\n",
    "print(df1)\n",
    "print(df1.sort_values(['a'],ascending = True))                 # 按照升序排序\n",
    "print(df1.sort_values(['a'],ascending = False))                # 按照降序排序\n",
    "print(\"--------------------------------------------------------------------------\")\n",
    "# ascending参数：设置升序降序，默认为升序\n",
    "# 单列排序\n",
    "\n",
    "df2 = pd.DataFrame({'a':[1,1,1,1,2,2,2,2],\n",
    "                  'b':list(range(8)),\n",
    "                  'c':list(range(8,0,-1))\n",
    "                   })\n",
    "print(df2)\n",
    "print(df2.sort_values(['a','c']))\n",
    "# 多列排序，按照列顺序排序   Note: 此处务必要注意！！！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "           a          b          c          d\n",
      "5  54.363034  28.464971  32.001933  21.609576\n",
      "4   8.664021  85.783805   3.670999  16.035448\n",
      "3  11.976784  77.968659  40.742603  86.147391\n",
      "2  54.331812  57.211603  38.410442  82.736831\n",
      "           a          b          c          d\n",
      "2  54.331812  57.211603  38.410442  82.736831\n",
      "3  11.976784  77.968659  40.742603  86.147391\n",
      "4   8.664021  85.783805   3.670999  16.035448\n",
      "5  54.363034  28.464971  32.001933  21.609576\n",
      "           a          b          c          d\n",
      "h  15.851084  29.929131  75.178962  78.714376\n",
      "s  36.305924  28.709192  18.253719  60.419313\n",
      "x  74.253887  51.978034  49.692612  59.671422\n",
      "g  17.858464  39.236763  83.080844  61.641289\n",
      "           a          b          c          d\n",
      "g  17.858464  39.236763  83.080844  61.641289\n",
      "h  15.851084  29.929131  75.178962  78.714376\n",
      "s  36.305924  28.709192  18.253719  60.419313\n",
      "x  74.253887  51.978034  49.692612  59.671422\n"
     ]
    }
   ],
   "source": [
    "# 排序二：索引排序：.sort_index\n",
    "\n",
    "df1 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                  index = [5,4,3,2],\n",
    "                  columns = list('abcd')\n",
    "                  )\n",
    "df2 = pd.DataFrame(np.random.rand(16).reshape(4,4)*100,\n",
    "                  index = ['h','s','x','g'],\n",
    "                  columns = list('abcd')\n",
    "                  )\n",
    "print(df1)\n",
    "print(df1.sort_index())\n",
    "print(df2)\n",
    "print(df2.sort_index())\n",
    "# 按照index排序\n",
    "# 默认 ascending=True, inplace=False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
